﻿using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Text;
using Dapper;
using Dapper.Contrib.Extensions;

namespace EC.Application.Impl
{
    using EC.Application.Interface;

    using EC.Entity;
    using EC.Entity.Enum;
    using EC.Entity.Request.Business;
    using EC.Entity.Request.User;
    using EC.Entity.Response.Merchant;
    using EC.Entity.Tables;
    using EC.Util;

    /// <summary>
    /// 商户接口
    /// </summary>
    public class BusinessServiceImpl: BusinessService
    {
        #region 注入
        /// <summary>
        /// 数据接口
        /// </summary>
        private readonly IDBSession _dbSession;


        /// <summary>
        /// 数据库上下文
        /// </summary>
        /// <param name="context">数据库上下文</param>
        public BusinessServiceImpl(IDBSession dbSession)
        {
            _dbSession = dbSession;
        }
        #endregion

        #region 商户
        /// <summary>
        /// 获取商户
        /// </summary>
        /// <param name="id">编号</param>
        /// <returns></returns>
        public MerchantResponse GetMerchant(int id)
        {
            var merchants = _dbSession.DbConnection.Query<MerchantResponse>("select * from merchant where Id=@Id", new { Id = id });

            var model = merchants.FirstOrDefault();
            if (model != null)
            {
                return model;
            }

            return null;
        }

        /// <summary>
        /// 充值
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public JResult SaveRecharge(SaveRechargeRequest request)
        {
            var response = new JResult()
            {
                Success = false
            };

            try
            {
                //充值金额
                if (string.IsNullOrEmpty(request.Amount))
                {
                    return new JResult()
                    {
                        Success = false,
                        Message = "充值金额最大保留三位小数，整数最多保留两位."
                    };
                }
                //var paymentRateReg = new Regex(@"^(([1-9]\d{0,1})|0)(?:\.[0-9]{1,3})?$");
                //if (!paymentRateReg.IsMatch(request.Amount))
                //{
                //    return new JResult()
                //    {
                //        Success = false,
                //        Message = "充值金额最大保留三位小数，整数最多保留两位."
                //    };
                //}

                var amount = Convert.ToDecimal(request.Amount);
                if (amount <= 0)
                {
                    return new JResult()
                    {
                        Success = false,
                        Message = "充值金额必须大于零."
                    };
                }

                // 密码
                if (string.IsNullOrEmpty(request.PassWord))
                {
                    return new JResult()
                    {
                        Success = false,
                        Message = "密码不给不能为空."
                    };
                }

                var users = _dbSession.DbConnection.Query<User>("select * from user where Id=@Id", new { Id = request.UserId });
                var user = users.FirstOrDefault();
                if (user == null)
                {
                    return new JResult()
                    {
                        Success = false,
                        Message = "暂无记录."
                    };
                }

                var oldPassWord = EncryptionUtil.EncryptWithMd5(request.PassWord);
                if (user.ConfirmPassWord != oldPassWord)
                {
                    return new JResult()
                    {
                        Success = false,
                        Message = "密码错误."
                    };
                }

                //事务开始
                _dbSession.Begin();

                var merchants = _dbSession.DbConnection.Query<Merchant>("select * from merchant where Id=@Id", new { Id = request.MerchantId }, _dbSession.DbTransaction);

                var merchant = merchants.FirstOrDefault();
                if (merchant == null)
                {
                    throw new Exception("暂无记录.");
                }

                //验证
                if (merchant.DepositBalance < amount)
                {
                    throw new Exception("余额不足.");
                }

                //结算

                //减去存款余额日志
                var depositBalanceLog = new BalanceLog()
                {
                    MerchantId = request.MerchantId,
                    Source = (int)BalanceLogSource.存款余额,
                    Type = (int)BalanceLogType.减,
                    Amount = amount,
                    BeforeBalance = merchant.DepositBalance,
                    AfterBalance = merchant.DepositBalance - amount,
                    Remark = "内充",
                    CreatedBy = request.UserId,
                    CreatedDate = DateTime.Now
                };

                //新增
                long depositBalanceLogResultId = _dbSession.DbConnection.Insert<BalanceLog>(depositBalanceLog, _dbSession.DbTransaction);

                if (depositBalanceLogResultId <= 0)
                {
                    throw new Exception("新增减去存款余额日志失败.");
                }

                //增加付款余额日志
                var paymentBalanceLog = new BalanceLog()
                {
                    MerchantId = request.MerchantId,
                    Source = (int)BalanceLogSource.付款余额,
                    Type = (int)BalanceLogType.加,
                    Amount = amount,
                    BeforeBalance = merchant.PaymentBalance,
                    AfterBalance = merchant.PaymentBalance + amount,
                    Remark = "内充",
                    CreatedBy = request.UserId,
                    CreatedDate = DateTime.Now
                };

                long paymentBalanceLogResultId = _dbSession.DbConnection.Insert<BalanceLog>(paymentBalanceLog, _dbSession.DbTransaction);

                if (paymentBalanceLogResultId <= 0)
                {
                    throw new Exception("新增付款余额日志失败.");
                }


                //余额
                int result = _dbSession.DbConnection.Execute("UPDATE merchant SET DepositBalance=DepositBalance-@Amount,PaymentBalance=PaymentBalance+@Amount WHERE Id=@Id", new { Amount = amount, Id = request.MerchantId }, _dbSession.DbTransaction);
                if (result <= 0)
                {
                    throw new Exception("更新账户失败");
                }

                response.Success = true;
                //提交事务
                _dbSession.Commit();
            }
            catch (Exception ex)
            {
                _dbSession.Rollback();

                response.Message = ex.Message;
            }

            return response;
        }

        /// <summary>
        /// 提现
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public JResult SaveWithdrawal(SaveWithdrawalRequest request)
        {
            var response = new JResult()
            {
                Success = false
            };

            //银行名字
            if (string.IsNullOrEmpty(request.BankName))
            {
                return new JResult()
                {
                    Success = false,
                    Message = "银行名字不能为空."
                };
            }
            //银行名字
            if (string.IsNullOrEmpty(request.CardName))
            {
                return new JResult()
                {
                    Success = false,
                    Message = "姓名不能为空."
                };
            }
            //卡号
            if (string.IsNullOrEmpty(request.CardNumber))
            {
                return new JResult()
                {
                    Success = false,
                    Message = "卡号不能为空."
                };
            }
            //金额
            if (string.IsNullOrEmpty(request.Amount))
            {
                return new JResult()
                {
                    Success = false,
                    Message = "金额不能为空."
                };
            }

            var paymentRateReg = new Regex(@"^(([1-9]\d{0,4})|0)(?:\.[0-9]{1,3})?$");
            if (!paymentRateReg.IsMatch(request.Amount))
            {
                return new JResult()
                {
                    Success = false,
                    Message = "充值金额最大保留三位小数，整数最多保留两位."
                };
            }

            var amount = Convert.ToDecimal(request.Amount);
            if (amount <= 0)
            {
                return new JResult()
                {
                    Success = false,
                    Message = "充值金额必须大于零."
                };
            }

            // 密码
            if (string.IsNullOrEmpty(request.PassWord))
            {
                return new JResult()
                {
                    Success = false,
                    Message = "密码不给不能为空."
                };
            }

            var users = _dbSession.DbConnection.Query<User>("select * from user where Id=@Id", new { Id = request.UserId });
            var user = users.FirstOrDefault();
            if (user == null)
            {
                return new JResult()
                {
                    Success = false,
                    Message = "暂无记录."
                };
            }

            var oldPassWord = EncryptionUtil.EncryptWithMd5(request.PassWord);
            if (user.ConfirmPassWord != oldPassWord)
            {
                return new JResult()
                {
                    Success = false,
                    Message = "密码错误."
                };
            }

            try
            {
                //事务开始
                _dbSession.Begin();

                var merchants = _dbSession.DbConnection.Query<Merchant>("select * from merchant where Id=@Id", new { Id = request.MerchantId }, _dbSession.DbTransaction);

                var merchant = merchants.FirstOrDefault();
                if (merchant == null)
                {
                    throw new Exception("暂无记录.");
                }

                //验证
                if (merchant.SettleSingle <= 0)
                {
                    throw new Exception("结算金额未设置.");
                }

                var total = amount + merchant.SettleSingle;

                //验证
                if (merchant.DepositBalance < total)
                {
                    throw new Exception("余额不足.");
                }

                //增加结算记录
                var settle = new Settle()
                {
                    MerchantId = request.MerchantId,
                    BankName = request.BankName,
                    CardName = request.CardName,
                    CardNumber = request.CardNumber,
                    Amount = amount,
                    Fee = merchant.SettleSingle,
                    Status = (int)SettleStatus.未处理,
                    CreatedBy = request.UserId,
                    CreatedDate = DateTime.Now
                };

                long settleResultId = _dbSession.DbConnection.Insert<Settle>(settle, _dbSession.DbTransaction);

                if (settleResultId <= 0)
                {
                    throw new Exception("新增结算失败.");
                }
                //日志
                //减去存款余额日志
                var depositBalanceLog = new BalanceLog()
                {
                    MerchantId = request.MerchantId,
                    Source = (int)BalanceLogSource.存款余额,
                    Type = (int)BalanceLogType.减,
                    Amount = total,
                    BeforeBalance = merchant.DepositBalance,
                    AfterBalance = merchant.DepositBalance - total,
                    Remark = $"提现金额：{amount},手续费:{settle.Fee}",
                    CreatedBy = request.UserId,
                    CreatedDate = DateTime.Now
                };
                //新增
                long depositBalanceLogResultId = _dbSession.DbConnection.Insert<BalanceLog>(depositBalanceLog, _dbSession.DbTransaction);

                if (depositBalanceLogResultId <= 0)
                {
                    throw new Exception("新增减去存款余额日志失败.");
                }
                //余额
                int result = _dbSession.DbConnection.Execute("UPDATE merchant SET DepositBalance=DepositBalance-@Amount WHERE Id=@Id and DepositBalance>=@Amount", new { Amount = total, Id = request.MerchantId }, _dbSession.DbTransaction);
                if (result <= 0)
                {
                    throw new Exception("更新账户失败");
                }

                response.Success = true;
                //提交事务
                _dbSession.Commit();
            }
            catch (Exception ex)
            {
                _dbSession.Rollback();

                response.Message = ex.Message;
            }

            return response;
        }
        #endregion

        #region 用户
        /// <summary>
        /// 修改密码
        /// </summary>
        /// <returns></returns>
        public JResult ResetPassWord(ResetPassWordRequest request)
        {
            var response = new JResult()
            {
                Success = false
            };

            try
            {
                var user = _dbSession.DbConnection.QueryFirst<User>("select * from user where Id=@Id", new { Id = request.Id });
                if (user == null)
                {
                    throw new Exception("用户记录不存在.");
                }

                if (string.IsNullOrEmpty(request.OldPassword))
                {
                    throw new Exception("请输入旧密码.");
                }

                if (string.IsNullOrEmpty(request.NewPassword))
                {
                    throw new Exception("请输入新密码.");
                }

                if (request.NewPassword != request.ConfirmNewPassword)
                {
                    throw new Exception("两次输入新密码不一样,请重新输入.");
                }

                var oldPassWord = EncryptionUtil.EncryptWithMd5(request.OldPassword);
                if (user.PassWord != oldPassWord)
                {
                    throw new Exception("旧密码错误！");
                }

                user.PassWord = EncryptionUtil.EncryptWithMd5(request.NewPassword);

                var updateSql = "UPDATE user SET PassWord=@PassWord WHERE Id=@Id";

                int result = _dbSession.DbConnection.Execute(updateSql, user);
                if (result <= 0)
                {
                    throw new Exception("更新失败");
                }
                response.Success = true;
            }
            catch (Exception ex)
            {
                response.Message = ex.Message;
            }

            return response;
        }
        #endregion
    }
}
